package com.ymt.bpm.service.platform.config.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ymt.bpm.dao.MDao;
import com.ymt.bpm.dao.Mapper;
import com.ymt.bpm.engine.EngineConst;
import com.ymt.bpm.model.Const.Oplog;
import com.ymt.bpm.model.PDict;
import com.ymt.bpm.model.PI18n;
import com.ymt.bpm.service.platform.config.DictService;
import com.ymt.bpm.service.platform.log.OpLogService;
import com.ymt.bpm.util.Const;
import com.ymt.bpm.util.DhxUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Johnny on 2017/9/20.
 */
@Service
public class DictServiceImpl implements DictService {

    private Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private MDao dao;

    @Autowired
    private OpLogService oplog;

    @Override
    public JSONObject query(String tenantId, String appId, String search, String sort,
                            String order, int offset, int limit, int timezoneOffset) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put("search", search);
        paramMap.put("sort", sort);
        paramMap.put("order", order);
        PageHelper.offsetPage(offset, limit);
        List<PDict> list = dao.selectList(Mapper.PDictMapper, "queryAll", paramMap);
        PageInfo pageInfo = new PageInfo(list);
        JSONObject rtn = new JSONObject();
        JSONArray rows = new JSONArray();
        if (list!=null && list.size()>0) {
            for (PDict dict : list) {
                JSONObject node = DhxUtil.toJsonWithDateAli(dict, Const.LANG_ZH, timezoneOffset);
                node.put("_ITEM_NO", ++offset);
                rows.add(node);
            }
        }
        rtn.put("rows", rows);
        rtn.put("total", pageInfo.getTotal());
        return rtn;
    }

    @Override
    public JSONObject save(String tenantId, String loginName, String displayName, PDict dict) {
        if (log.isDebugEnabled()) {
            log.debug("save dict.id="+dict.getId());
        }
        if (tenantId!=null && StringUtils.isNumeric(tenantId)) {
            dict.setTenantId(Integer.parseInt(tenantId));
        }
        JSONObject rtn = new JSONObject();
        int rs = 0;
        if (dict.getId()==null || dict.getId()==0L) {
            rs = dao.insert(Mapper.PDictMapper, "insertSelective", dict);

            //记录日志
            oplog.bizlog(tenantId, loginName, displayName, null, Oplog.OP.CREATE, Oplog.CODE.DICT, dict.getType());
        } else {
            rs = dao.update(Mapper.PDictMapper, "updateByPrimaryKeySelective", dict);

            //记录日志
            oplog.bizlog(tenantId, loginName, displayName, null, Oplog.OP.UPDATE, Oplog.CODE.DICT, dict.getType());
        }
        rtn.put(Const.AJAX_RESULT, rs);
        return rtn;
    }

    @Override
    public String checkAttr(String tenantId, String attrName, String value, Long id) {
        if (log.isDebugEnabled()) {
            log.debug("checkAttr tenantId="+tenantId);
            log.debug("checkAttr attrName="+attrName);
            log.debug("checkAttr value="+value);
            log.debug("checkAttr id="+id);
        }
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put("value", value);
        paramMap.put("id", id);
        int rs = dao.selectOne(Mapper.PDictMapper, "checkAttr"+ StringUtils.capitalize(attrName), paramMap);
        if (log.isDebugEnabled()) {
            log.debug("checkAttr rs="+rs);
        }
        return rs>0 ? "false" : "true";
    }

    @Override
    public JSONObject delete(String tenantId, String loginName, String displayName, Long id) {
        JSONObject rtn = new JSONObject();
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put("id", id);
        PDict dict = dao.selectOne(Mapper.PDictMapper, "selectByPrimaryKey", id);
        int rs = dao.delete(Mapper.PDictMapper, "deleteById", paramMap);
        rtn.put(Const.AJAX_RESULT, rs);

        //记录日志
        oplog.bizlog(tenantId, loginName, displayName, null, Oplog.OP.DELETE, Oplog.CODE.DICT, dict.getType());

        return rtn;
    }

    @Override
    public JSONObject queryValue(String tenantId, Long id) {
        JSONObject rtn = new JSONObject();
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put("id", id);
        List<PI18n> list = dao.selectList(Mapper.PI18nMapper, "queryValueById", paramMap);

        //dhx
        /*JSONArray rows = new JSONArray();
        if (list!=null && list.size()>0) {
            for (int i=0; i<list.size(); i++) {
                JSONObject row = new JSONObject();
                JSONArray datas = new JSONArray();
                datas.add(list.get(i).getSort());
                datas.add(list.get(i).getRelationkey());
                datas.add(list.get(i).getLang());
                datas.add(list.get(i).getValue());
                row.put(DhxUtil.ID, i+1);
                row.put(DhxUtil.DATA, datas);
                rows.add(row);
            }
        }
        rtn.put(DhxUtil.ROWS, rows);
        rtn.put(DhxUtil.TOTAL_COUNT, rows!=null ? rows.size() : 0);*/

        //bootstrap table
        JSONArray rows = new JSONArray();
        if (list!=null && list.size()>0) {
            rows = DhxUtil.toJsonWithDate(list, Const.LANG_ZH, 0);
        }
        rtn.put(DhxUtil.ROWS, rows);
        rtn.put("total", rows!=null ? rows.size() : 0);

        return rtn;
    }

    @Override
    public JSONObject saveValue(String tenantId,
                                String loginName, String displayName,
                                Long id, String type, String typedesc, String relationkey, String zh, String en, Short sort) {
        JSONObject rtn = new JSONObject();
        PI18n pzh = new PI18n();
        PI18n pen = new PI18n();
        if (tenantId!=null && StringUtils.isNumeric(tenantId)) {
            pzh.setTenantId(Integer.parseInt(tenantId));
            pen.setTenantId(Integer.parseInt(tenantId));
        }
        pzh.setId(id);
        pen.setId(id);
        pzh.setType(type);
        pen.setType(type);
        pzh.setTypedesc(typedesc);
        pen.setTypedesc(typedesc);
        pzh.setRelationkey(relationkey);
        pen.setRelationkey(relationkey);
        pzh.setLang(Const.LANG_ZH);
        pen.setLang(Const.LANG_EN);
        pzh.setSort(sort);
        pen.setSort(sort);
        pzh.setCategory("ENUMERATION");
        pen.setCategory("ENUMERATION");
        pzh.setTarget("BPM");
        pen.setTarget("BPM");
        pzh.setValue(zh);
        pen.setValue(en);
        int rs = dao.insert(Mapper.PI18nMapper, "replaceSelective", pzh);
        rs += dao.insert(Mapper.PI18nMapper, "replaceSelective", pen);
        rtn.put(Const.AJAX_RESULT, rs);

        //记录日志
        oplog.bizlog(tenantId, loginName, displayName, null, Oplog.OP.CREATE, Oplog.CODE.DICT_VALUE, pzh.getRelationkey());

        return rtn;
    }

    @Override
    public String checkValue(String tenantId, String relationkey, String type, Long id) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put("relationkey", relationkey);
        paramMap.put("type", type);
        paramMap.put("id", id);
        int rs = dao.selectOne(Mapper.PI18nMapper, "checkRelationkey", paramMap);
        if (log.isDebugEnabled()) {
            log.debug("checkAttr rs="+rs);
        }
        return rs>0 ? "false" : "true";
    }

    @Override
    public JSONObject delValue(String tenantId,
                               String loginName, String displayName,
                               String relationkey, Short sort, String type, Long id) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put("relationkey", relationkey);
        paramMap.put("type", type);
        paramMap.put("id", id);
        paramMap.put("sort", sort);
        int rs = dao.delete(Mapper.PI18nMapper, "deleteByRelationkey", paramMap);
        rs += dao.update(Mapper.PI18nMapper, "updateOrderAfterDel", paramMap);
        JSONObject rtn = new JSONObject();
        rtn.put(Const.AJAX_RESULT, rs);

        //记录日志
        oplog.bizlog(tenantId, loginName, displayName, null, Oplog.OP.DELETE, Oplog.CODE.DICT_VALUE, relationkey);

        return rtn;
    }

    @Override
    @Transactional(EngineConst.TRANSACTION_MANAGER)
    public JSONObject reorderValue(String tenantId,
                                   String loginName, String displayName,
                                   String sorts, String type, Long id) {
        JSONObject rtn = new JSONObject();
        JSONObject sortsJo = JSONObject.parseObject(sorts);
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        for (String relationkey : sortsJo.keySet()) {
            Map<String, Object> paramMap = new HashMap<String, Object>();
            paramMap.put(Const.TENANT_ID, tenantId);
            paramMap.put("sort", sortsJo.getIntValue(relationkey));
            paramMap.put("relationkey", relationkey);
            paramMap.put("type", type);
            paramMap.put("id", id);
            list.add(paramMap);
        }
        int rs = dao.batchUpdate(Mapper.PI18nMapper, "updateSort", list);
        rtn.put(Const.AJAX_RESULT, rs);

        //记录日志
        oplog.bizlog(tenantId, loginName, displayName, null, Oplog.OP.REORDER, Oplog.CODE.DICT_VALUE, type);

        return rtn;
    }

    @Override
    public JSONObject queryDictDhx(String tenantId, String appId, String args, String ordercolumns, String lang, int fromRow, int toRow, int timezoneOffset) {
        Map<String, Object> params = new HashMap<String,Object>();
        Map<String, Object> bo = new HashMap<String,Object>();
        if (tenantId!=null) {
            bo.put(Const.TENANT_ID, tenantId);
        }
        bo.put("appId", appId);
        params.put("bo", bo);
        if (args!=null) {
            bo.putAll(JSONObject.parseObject(args));
        }
        params.put("fromRow", fromRow-1);
        params.put("toRow", toRow);
        params.put("rows", toRow - fromRow + 1);
        params.put("orderby", DhxUtil.parseGridOrderBy(ordercolumns));
        List<Map<String,?>> list = dao.selectList(Mapper.PDictMapper, "pagingSelect", params);
        int total = dao.selectOne(Mapper.PDictMapper, "pagingSelectCount", params);
        String[] cols = new String[]{"TYPE","TYPEDESC", "ID"};
        return DhxUtil.toGridJson(list,
                cols, fromRow, total, timezoneOffset, lang);
    }

}
